home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Demo / tkinter / guido / rmt.py < prev    next >
Text File  |  1995-12-21  |  4KB  |  160 lines

  1. #! /usr/local/bin/python
  2.  
  3. # A Python program implementing rmt, an application for remotely
  4. # controlling other Tk applications.
  5. # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.
  6.  
  7. # Note that because of forward references in the original, we
  8. # sometimes delay bindings until after the corresponding procedure is
  9. # defined.  We also introduce names for some unnamed code blocks in
  10. # the original because of restrictions on lambda forms in Python.
  11.  
  12. # XXX This should be written in a more Python-like style!!!
  13.  
  14. from Tkinter import *
  15.  
  16. # 1. Create basic application structure: menu bar on top of
  17. # text widget, scrollbar on right.
  18.  
  19. root = Tk()
  20. tk = root.tk
  21. mBar = Frame(root, {'relief': 'raised', 'bd': 2,
  22.             Pack: {'side': 'top', 'fill': 'x'}})
  23. f = Frame(root)
  24. f.pack({'expand': 1, 'fill': 'both'})
  25. s = Scrollbar(f, {'relief': 'flat',
  26.           Pack: {'side': 'right', 'fill': 'y'}})
  27. t = Text(f, {'relief': 'raised', 'bd': 2, 'yscrollcommand': (s, 'set'),
  28.          'setgrid': 1,
  29.          Pack: {'side': 'left', 'fill': 'both', 'expand': 1}})
  30.  
  31. t.tag_config('bold', {'font': '-Adobe-Courier-Bold-R-Normal-*-120-*'}) 
  32. s['command'] = (t, 'yview')
  33. root.title('Tk Remote Controller')
  34. root.iconname('Tk Remote')
  35.  
  36. # 2. Create menu button and menus.
  37.  
  38. file = Menubutton(mBar, {'text': 'File', 'underline': 0,
  39.              Pack: {'side': 'left'}})
  40. file_m = Menu(file)
  41. file['menu'] = file_m
  42. file_m_apps = Menu(file_m)
  43. file_m.add('cascade', {'label': 'Select Application', 'underline': 0,
  44.                'menu': file_m_apps})
  45. file_m.add('command', {'label': 'Quit', 'underline': 0, 'command': 'exit'})
  46.  
  47. # 3. Create bindings for text widget to allow commands to be
  48. # entered and information to be selected.  New characters
  49. # can only be added at the end of the text (can't ever move
  50. # insertion point).
  51.  
  52. def single1(e):
  53.     x = e.x
  54.     y = e.y
  55.     t.setvar('tk_priv(selectMode)', 'char')
  56.     t.mark_set('anchor', At(x, y))
  57.     # Should focus W
  58. t.bind('<1>', single1)
  59.  
  60. def double1(e):
  61.     x = e.x
  62.     y = e.y
  63.     t.setvar('tk_priv(selectMode)', 'word')
  64.     t.tk_textSelectTo(At(x, y))
  65. t.bind('<Double-1>', double1)
  66.  
  67. def triple1(e):
  68.     x = e.x
  69.     y = e.y
  70.     t.setvar('tk_priv(selectMode)', 'line')
  71.     t.tk_textSelectTo(At(x, y))
  72. t.bind('<Triple-1>', triple1)
  73.  
  74. def returnkey(e):
  75.     t.insert(AtInsert(), '\n')
  76.     invoke()
  77. t.bind('<Return>', returnkey)
  78.  
  79. def controlv(e):
  80.     t.insert(AtInsert(), t.selection_get())
  81.     t.yview_pickplace(AtInsert())
  82.     if t.index(AtInsert())[-2:] == '.0':
  83.         invoke()
  84. t.bind('<Control-v>', controlv)
  85.  
  86. # 4. Procedure to backspace over one character, as long as
  87. # the character isn't part of the prompt.
  88.  
  89. def backspace(e):
  90.     if t.index('promptEnd') != t.index('insert - 1 char'):
  91.         t.delete('insert - 1 char', AtInsert())
  92.         t.yview_pickplace(AtInsert())
  93. t.bind('<BackSpace>', backspace)
  94. t.bind('<Control-h>', backspace)
  95. t.bind('<Delete>', backspace)
  96.  
  97.  
  98. # 5. Procedure that's invoked when return is typed:  if
  99. # there's not yet a complete command (e.g. braces are open)
  100. # then do nothing.  Otherwise, execute command (locally or
  101. # remotely), output the result or error message, and issue
  102. # a new prompt.
  103.  
  104. def invoke():
  105.     cmd = t.get('promptEnd + 1 char', AtInsert())
  106.     if t.getboolean(tk.call('info', 'complete', cmd)): # XXX
  107.         if app == root.winfo_name():
  108.             msg = tk.call('eval', cmd) # XXX
  109.         else:
  110.             msg = t.send(app, cmd)
  111.         if msg:
  112.             t.insert(AtInsert(), msg + '\n')
  113.         prompt()
  114.     t.yview_pickplace(AtInsert())
  115.  
  116. def prompt():
  117.     t.insert(AtInsert(), app + ': ')
  118.     t.mark_set('promptEnd', 'insert - 1 char')
  119.     t.tag_add('bold', 'insert linestart', 'promptEnd')
  120.  
  121. # 6. Procedure to select a new application.  Also changes
  122. # the prompt on the current command line to reflect the new
  123. # name.
  124.  
  125. def newApp(appName):
  126.     global app
  127.     app = appName
  128.     t.delete('promptEnd linestart', 'promptEnd')
  129.     t.insert('promptEnd', appName + ':')
  130.     t.tag_add('bold', 'promptEnd linestart', 'promptEnd')
  131.  
  132. def fillAppsMenu():
  133.     file_m_apps.add('command')
  134.     file_m_apps.delete(0, 'last')
  135.     names = root.winfo_interps()
  136.     names = map(None, names) # convert tuple to list
  137.     names.sort()
  138.     for name in names:
  139.         try:
  140.             root.send(name, 'winfo name .')
  141.         except TclError:
  142.             # Inoperative window -- ignore it
  143.             pass
  144.         else:
  145.             file_m_apps.add('command', {'label': name,
  146.                             'command':
  147.                             lambda name=name:
  148.                             newApp(name)})
  149.  
  150. file_m_apps['postcommand'] = fillAppsMenu
  151. mBar.tk_menuBar(file)
  152.  
  153. # 7. Miscellaneous initialization.
  154.  
  155. app = root.winfo_name()
  156. prompt()
  157. t.focus()
  158.  
  159. root.mainloop()
  160.